﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuadRemote.Core
{
    class CommandOut
    {
        public byte[] body;
        

        public byte packetId;
        public Boolean confirmed;
        
        public long timeSentAt;
        public long timeQueuedAt;
        private int timeout = 5000;

        public CommandIn responsePacket;

        public Boolean eventTimeout = false;
        public Boolean eventResponse = false;

        public delegate void callbackFunc(CommandOut cmd);

        public callbackFunc callback;
        public Boolean hasCallback;
        private CommandId commandId;

        public CommandOut(CommandId command)
        {
            this.body = new byte[1];
            this.body[0] = (byte)command;
        }

        public CommandOut(CommandId command, params byte[] body)
        {
            this.body = new byte[body.Length + 1];
            Array.Copy(body,0,this.body,1,body.Length);
            this.body[0] = (byte)command;
        }

        public CommandOut(CommandId command, params byte[][] body)
        {
            int len = 0;
            foreach (byte[] b in body)
                len += b.Length;

            this.body = new byte[len + 1];
            this.body[0] = (byte)command;
            int pos = 1;
            foreach (byte[] b in body)
            {
                Array.Copy(b, 0, this.body, pos, b.Length);
                pos += b.Length;
            }
        }

        public CommandOut callbackOnResponsePacket(CommandId command, callbackFunc call)
        {
            Bluetooth.instance().commandParsers[(int)command] += responsePacketReceived;
            callback += call;
            hasCallback = true;
            return this;
        }

        public CommandOut setTimeout(int ms)
        {
            this.timeout = ms;
            return this;
        }

        private void responsePacketReceived(CommandIn args)
        {
            Bluetooth.instance().commandParsers[(int)args.command] -= responsePacketReceived;

            responsePacket = args;

            Bluetooth.instance().dequeueCommand(this);

            eventResponse = true;

            if (hasCallback)
            {
                callback(this);
            }
        }

        public CommandOut send()
        {
            timeQueuedAt = DateTime.Now.Ticks;
            Bluetooth.instance().queueCommand(this);
            return this;
        }

        public void checkTimeout()
        {
            if (DateTime.Now.Ticks > timeQueuedAt + timeout * TimeSpan.TicksPerMillisecond)
            {
                eventTimeout = true;
                Bluetooth.instance().dequeueCommand(this);

                if (hasCallback)
                    callback(this);
            }
        }


    }
}
